cmake_minimum_required(VERSION 3.15)
project(opentelemetry_demo)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Find required packages
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(Threads REQUIRED)
find_package(opentelemetry-cpp CONFIG REQUIRED)

# Create executables
add_executable(node_a src/node_a.cpp)
add_executable(node_b src/node_b.cpp)
add_executable(node_c src/node_c.cpp)

# Create cross-node demo executables
add_executable(publisher_node src/cross_node_demo/publisher_node.cpp)
add_executable(processor_node src/cross_node_demo/processor_node.cpp)
add_executable(consumer_node src/cross_node_demo/consumer_node.cpp)

# Create cross-node demo executables with trace propagation
add_executable(publisher_node_with_trace src/cross_node_demo/publisher_node_with_trace.cpp)
add_executable(processor_node_with_trace src/cross_node_demo/processor_node_with_trace.cpp)
add_executable(consumer_node_with_trace src/cross_node_demo/consumer_node_with_trace.cpp)

# Create resource test executables
add_executable(resource_monitor src/resource_test/resource_monitor.cpp)
add_executable(opentelemetry_performance_monitor src/resource_test/opentelemetry_performance_monitor.cpp)

# Create individual performance test executables
add_executable(basic_span_test src/resource_test/basic_span_test.cpp)
add_executable(high_frequency_test src/resource_test/high_frequency_test.cpp)
add_executable(large_attribute_test src/resource_test/large_attribute_test.cpp)
add_executable(concurrent_test src/resource_test/concurrent_test.cpp)
add_executable(nesting_test src/resource_test/nesting_test.cpp)
add_executable(memory_stress_test src/resource_test/memory_stress_test.cpp)
add_executable(quick_performance_demo src/resource_test/quick_performance_demo.cpp)
add_executable(exporter_impact_test src/resource_test/exporter_impact_test.cpp)
add_executable(simple_exporter_test src/resource_test/simple_exporter_test.cpp)
add_executable(optimized_performance_test src/resource_test/optimized_performance_test.cpp)
add_executable(io_blocking_comparison src/resource_test/io_blocking_comparison.cpp)

# Create single process demo executable
add_executable(function_tracing_demo src/single_process_demo/function_tracing_demo.cpp)

# Link libraries
target_link_libraries(node_a
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(node_b
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(node_c
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(publisher_node
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(processor_node
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(consumer_node
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(publisher_node_with_trace
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(processor_node_with_trace
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(consumer_node_with_trace
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(resource_monitor
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(opentelemetry_performance_monitor
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

# Link libraries for individual performance tests
target_link_libraries(basic_span_test
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(high_frequency_test
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(large_attribute_test
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(concurrent_test
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(nesting_test
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(memory_stress_test
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(quick_performance_demo
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(exporter_impact_test
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(simple_exporter_test
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(optimized_performance_test
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(io_blocking_comparison
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

target_link_libraries(function_tracing_demo
    rclcpp::rclcpp
    ${std_msgs_LIBRARIES}
    ${geometry_msgs_LIBRARIES}
    opentelemetry-cpp::api
    opentelemetry-cpp::sdk
    opentelemetry-cpp::trace
    opentelemetry-cpp::ostream_span_exporter
    Threads::Threads
)

# Install executables
install(TARGETS
    node_a
    node_b
    node_c
    publisher_node
    processor_node
    consumer_node
    publisher_node_with_trace
    processor_node_with_trace
    consumer_node_with_trace
    resource_monitor
    opentelemetry_performance_monitor
    basic_span_test
    high_frequency_test
    large_attribute_test
    concurrent_test
    nesting_test
    memory_stress_test
    quick_performance_demo
    exporter_impact_test
    simple_exporter_test
    optimized_performance_test
    io_blocking_comparison
    function_tracing_demo
    DESTINATION lib/${PROJECT_NAME}
)

# Install launch files
install(DIRECTORY
    launch
    DESTINATION share/${PROJECT_NAME}/
)

# Compiler options
target_compile_options(node_a PRIVATE -Wall -Wextra -O2)
target_compile_options(node_b PRIVATE -Wall -Wextra -O2)
target_compile_options(node_c PRIVATE -Wall -Wextra -O2)
target_compile_options(publisher_node PRIVATE -Wall -Wextra -O2)
target_compile_options(processor_node PRIVATE -Wall -Wextra -O2)
target_compile_options(consumer_node PRIVATE -Wall -Wextra -O2)
target_compile_options(publisher_node_with_trace PRIVATE -Wall -Wextra -O2)
target_compile_options(processor_node_with_trace PRIVATE -Wall -Wextra -O2)
target_compile_options(consumer_node_with_trace PRIVATE -Wall -Wextra -O2)
target_compile_options(resource_monitor PRIVATE -Wall -Wextra -O2)
target_compile_options(opentelemetry_performance_monitor PRIVATE -Wall -Wextra -O2)
target_compile_options(basic_span_test PRIVATE -Wall -Wextra -O2)
target_compile_options(high_frequency_test PRIVATE -Wall -Wextra -O2)
target_compile_options(large_attribute_test PRIVATE -Wall -Wextra -O2)
target_compile_options(concurrent_test PRIVATE -Wall -Wextra -O2)
target_compile_options(nesting_test PRIVATE -Wall -Wextra -O2)
target_compile_options(memory_stress_test PRIVATE -Wall -Wextra -O2)
target_compile_options(quick_performance_demo PRIVATE -Wall -Wextra -O2)
target_compile_options(exporter_impact_test PRIVATE -Wall -Wextra -O2)
target_compile_options(simple_exporter_test PRIVATE -Wall -Wextra -O2)
target_compile_options(optimized_performance_test PRIVATE -Wall -Wextra -O2)
target_compile_options(io_blocking_comparison PRIVATE -Wall -Wextra -O2)
target_compile_options(function_tracing_demo PRIVATE -Wall -Wextra -O2)

ament_package()
